#ifndef _FS_H_
#define _FS_H_

#include <sys/types.h>

#define READ 0
#define WRITE 1

void buffer_init(long buffer_end);

#define MAJOR(a) (((unsigned)(a)) >> 8)
#define MINOR(a) ((a) & 0xff)

#define SUPER_MAGIC 0x137F

#define NR_HASH 307
#define NR_BUFFERS nr_buffers
#define BLOCK_SIZE 1024

struct buffer_head {
    char *b_data;               // 指向数据块（1KB）的指针
    unsigned long b_blocknr;    // 逻辑块号
    unsigned short b_dev;       // 设备号，0-空闲
    unsigned char b_uptodate;   // 是否更新
    unsigned char b_dirt;       // 脏位，0-未修改，1-修改过
    unsigned char b_count;      // 使用此结构的用户数
    unsigned char b_lock;       // 0 - 未上锁，1 - 上锁
    struct task_struct *b_wait; // 指向该缓冲区解锁的任务
    struct buffer_head *b_prev; // hash队列的上一块
    struct buffer_head *b_next; // hash队列的下一块
    struct buffer_head *b_prev_free;    // 空闲表上一块
    struct buffer_head *b_next_free;    // 空闲表下一块
};

struct d_inode {
    unsigned short i_mode;      // 文件的类型和属性(rwx)
    unsigned short i_uid;       // 文件所有者的用户id
    unsigned long i_size;       // 文件长度（字节）
    unsigned long i_time;       // 修改时间（从1970.1.1:0时算起，单位：秒）
    unsigned char i_gid;        // 文件所有者的组id
    unsigned char i_nlinks;     // 链接数
    unsigned short i_zone[9];   // 文件占用的逻辑块的块号
                                // zone[0]-zone[6]是直接块号
                                // zone[7]是一次间接块号
                                // zone[8]是二次间接块号
};

struct d_super_block {
    unsigned short s_ninodes;       // i节点数
    unsigned short s_nzones;        // 逻辑块数
    unsigned short s_imap_blocks;   // i节点位图所占块数
    unsigned short s_zmap_blocks;   // 逻辑块位图所占块数
    unsigned short s_firstdatazone; // 数据区第一个逻辑块的块号
    unsigned short s_log_zone_size; // log2(数据块数/逻辑块)
    unsigned long s_max_size;       // 最大文件长度
    unsigned short s_magic;         // 文件系统魔数
};

extern void check_disk_change(int dev);
extern int floppy_change(unsigned int nr);
extern int ticks_to_floppy_on(unsigned int dev);
extern void floppy_on(unsigned int dev);
extern void floppy_off(unsigned int dev);
extern void ll_rw_block(int rw, struct buffer_head *bh);
extern struct buffer_head *bread(int dev, int block);
extern int ROOT_DEV;

extern void mount_root(void);

#endif
